package asm;

import aj.org.objectweb.asm.ClassReader;
import aj.org.objectweb.asm.ClassVisitor;
import aj.org.objectweb.asm.ClassWriter;
import aj.org.objectweb.asm.MethodVisitor;

import java.io.IOException;

/**
 * Asm
 * 看英文文档如果第一段没用略过看有用的。
 * Call api 开始看
 *
 * __asm__ 用的是c的引用 在c里面 __asm__{}可以直接写汇编 所以asm其实就是汇编语言。
 * Asm就是汇编语言 这里指是java的汇编语言。 java的汇编就是java的class
 *
 * java class file 解释
 * target classes
 * 用记事本打开就行二进制文件
 * cafe babe class 的开头
 * magic          魔数
 * version        类是哪个版本的
 * constant_pool  常量池
 * access_flags   用来标识类是否具有pulbic/abstract/interface/final等修饰符。
 * this_class     当前class的名称。
 * super_class    父类名称
 * https://www.cnblogs.com/qingquanzi/p/8795543.html
 *
 * 需要非常透彻了解 需要读java虚拟机规范。 阿里自己虚拟机 龙井
 *
 * https://docs.oracle.com/javase/specs/jvms/se15/jvms15.pdf 3 在第四章有跟字节有关的
 * https://docs.oracle.com/javase/specs/index.html 2
 * https://docs.oracle.com/en/java/javase/ 1
 *
 * idea 直接查看一个类的二进制码
 * 光标进入类体里面
 * 顶部菜单->view->show bytecode->弹出当前类编译后的二进制码  javap
 * 二进制文件
 * init 构造方法
 * 默认调用的父类构造方法 Object.<init>
 * 看一个类的初始化过程看这个方式最清楚。
 * 看懂这个需要能懂java的汇编指令是什么意思。
 *
 * 插件看
 * idea -> pre -> plugin -> jclasslib
 * view->showbytecode
 *
 * 如果显示有问题重新运行（编译）下。
 *
 * asm pdf
 * https://asm.ow2.io/asm4-guide.pdf
 * 细看2.2.2. Parsing classes
 *
 * asm 动态生成代理的全流程
 * // 先把被代理的类拿进来
 * ClassReader cr = new ClassReader(
 *                 Asm.class.getClassLoader().getResourceAsStream("asm.Tank")
 *         );
 *
 * // 创建一个写类
 * ClassWriter cw = new ClassWriter(0);
 *
 * 构建 visitor 传入cw
 * cv
 *
 * cr.accept(cv, 0);
 * byte[] b2 = cw.toByteArray();
 *
 * 如果直接
 * cr.accept(cw,0) 就是把原来的做个拷贝 cr 写到了cw上
 *
 * cr 接受了 cv cv又接受了cw 形成了链条模式
 * cr读取 经过cv处理最后通过cw写出去
 */
public class Asm {
    public static void main(String[] args) throws IOException {
        int i = 0;
        int b = i++;
        System.out.println("asm"+b);

        // java.lang.Runnable 这个是没有源代码的 类从内存直接读类的结构。
//        ClassReader cr = new ClassReader("java.lang.Runnable");
//
//        System.out.println("test");

        // ClassReader 读取一个class的结构

        // ClassWriter 写一个class的结构。 动态代理proxy0.class生成方式。
//        ClassWriter cw = new ClassWriter(0);  动态生成字节码 写到硬盘需要file写字节到硬盘

//        System.out.println(cw);


//        ClassReader cr = new ClassReader(
//                Asm.class.getClassLoader().getResourceAsStream("asm/Tank.class")
//        );

//        ClassWriter cw = new ClassWriter(0);




    }
}
